/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.brain.conf.manager;

import com.brain.conf.dto.MonedaDto;
import com.brain.conf.dto.TipoCambioDto;
import com.brain.core.manager.*;
import com.brain.core.common.UtilCore;
import com.brain.core.configuracion.WebServletContextListener;
import com.brain.core.exception.DAOException;
import com.brain.core.hibernate.dao.DAOGenerico;
import com.brain.core.view.mbean.ApplicationMBean;
import com.brain.core.view.mbean.SessionMBean;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

/**
 *
 * @author Indra
 */
@Service
public class TipoCambioManager extends ComunManager<TipoCambioDto> implements Serializable {

    private static Logger logger = Logger.getLogger(TipoCambioManager.class);
    private Long idEntidad = 135L;
    @Resource
    private DAOGenerico<TipoCambioDto> springHibernateDao;
    @Resource
    private RecursosManager recursosManager;
    private final String url = "/pages/conf/tipoCambio/tipoCambio.xhtml";
    private final String urlLista = "/pages/conf/tipoCambio/listaTipoCambio.xhtml";
    private Long iteracionCompraVenta = 2L;

    /**
     * Obtener Todos los Tipos de Cambio
     *
     * @return
     * @throws DAOException
     */
    public List<TipoCambioDto> obtenerTodos() throws DAOException {
        return springHibernateDao.listarTodosDtos(TipoCambioDto.class);
    }

    /**
     * Obtener Tipos de Cambio por Id
     *
     * @param id
     * @return
     * @throws DAOException
     */
    public TipoCambioDto obtenerPorId(Long id) throws DAOException {
        return springHibernateDao.obtenerDtoPorId(TipoCambioDto.class, id);
    }

    /**
     * Metodo para obtener Tipos de Cambio activos
     *
     * @return
     * @throws DAOException
     */
    public List<TipoCambioDto> obtenerActivos() throws DAOException {
        Map<String, Object> filtros = new HashMap<String, Object>();
        filtros.put("estado", Boolean.TRUE);
        Map<String, String> orden = new HashMap<String, String>();
        orden.put("id", "asc");
        return springHibernateDao.obtenerDtosConFiltrosConOrden(TipoCambioDto.class, filtros, orden);
    }

    /**
     * Metodo para obtener Tipos de Cambio por padre
     *
     * @return
     * @throws DAOException
     */
    public List<TipoCambioDto> obtenerPorPadre(TipoCambioDto dto) throws DAOException {
        Map<String, Object> filtros = new HashMap<String, Object>();
        filtros.put("estado", Boolean.TRUE);
        filtros.put("padreDto.id", dto.getId());
        Map<String, String> orden = new HashMap<String, String>();
        orden.put("id", "asc");
        return springHibernateDao.obtenerDtosConFiltrosConOrden(TipoCambioDto.class, filtros, orden);
    }

    /**
     * Metodo para obtener Tipos de Cambio por un mapa de filtros y un mapa de
     * orden
     *
     * @param filtros
     * @param orden
     * @return
     * @throws DAOException
     */
    public List<TipoCambioDto> obtenerConFiltroConOrden(Map<String, Object> filtros, Map<String, String> orden) throws DAOException {
        return springHibernateDao.obtenerDtosConFiltrosConOrden(TipoCambioDto.class, filtros, orden);
    }

    /**
     * Metodo para obtener filtros de acuerdo a un filtro
     *
     * @param dtoFiltro filtros
     * @return lista de empresa
     * @throws DAOException
     */
    public List<TipoCambioDto> obtener(Date fechaInicio, Date fechaFin, TipoCambioDto dtoFiltro) throws DAOException {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        List<Object> listaParametros = new ArrayList<Object>();
        String hqsql = "select e from TipoCambioDto as e where e.id = e.id ";

        if (dtoFiltro.getId() != null && !dtoFiltro.getId().equals(0L)) {
            hqsql += " and e.id = ?";
            listaParametros.add(dtoFiltro.getId());
        }


        if (fechaInicio != null) {
            Calendar c = Calendar.getInstance();
            c.setTime(fechaInicio);
            c.set(Calendar.HOUR, 0);
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);
            hqsql += " and e.fechaCambio >= ? ";
            listaParametros.add(c.getTime());
        }

        if (fechaFin != null) {
            Calendar c = Calendar.getInstance();
            c.setTime(fechaFin);
            c.set(Calendar.HOUR, 0);
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);
            hqsql += " and e.fechaCambio <= ? ";
            listaParametros.add(c.getTime());
        }

        if (dtoFiltro.getEstado() != null) {
            hqsql += " and e.estado = ?";
            listaParametros.add(dtoFiltro.getEstado());
        }
        
        if (sessionMBean.getOrganizacionDto() != null && sessionMBean.getOrganizacionDto().getId() != null) {
            hqsql += " and e.organizacionDto.id = ?";
            listaParametros.add(sessionMBean.getOrganizacionDto().getId());
        }
        
        hqsql += " order by e.id desc";
        return springHibernateDao.ejecutarQuery(hqsql, listaParametros);
    }

    /**
     * Meotodo para validar Fechas de filtro
     *
     * @param fechaInicio
     * @param fechaFin
     * @return
     */
    public Boolean validarFechasFiltro(Date fechaInicio, Date fechaFin) {
        String mensajeTrx = "";
        if (fechaInicio != null && fechaFin != null) {
            if (fechaInicio.before(fechaFin)) {
                return true;
            } else {
                mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("tipo.cambio.fecha.mensaje.error");
                recursosManager.showWarning(mensajeTrx);
                return false;
            }
        } else {
            return true;
        }
    }

    /**
     * Metodo para guardar, editar Tipos de Cambio
     *
     * @param dto
     * @return
     */
    public String guardar(TipoCambioDto dto) {

        String to = null;
        String mensajeTrx = "";
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        ApplicationMBean applicationMBean = (ApplicationMBean) WebServletContextListener.getApplicationContext().getBean("applicationMBean");

        if (sessionMBean.getAccion() == applicationMBean.getNuevo()) {
            try {
                dto.setFechaCambio(UtilCore.Fecha.obtenerFechaActualDate());
                dto.setUsuarioDto(sessionMBean.getSessionUsuarioDto());
                dto.setUsuarioCreacionDto(sessionMBean.getSessionUsuarioDto());
                dto.setFechaCreacion(UtilCore.Fecha.obtenerFechaActualDate());
                dto.setTerminalCreacion(sessionMBean.getSessionTerminal());
                UtilCore.General.toUpperCaseDto(dto);
                nuevo(dto);

                mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
                recursosManager.showMessage(mensajeTrx);

                to = "";//retroceder();
            } catch (Exception ex) {
                mensajeTrx = ex.getMessage();
                recursosManager.showError(ex.getMessage());
                logger.error(mensajeTrx);

                to = null;
            }
        } else if (sessionMBean.getAccion() == applicationMBean.getEditar()) {
            try {
                UtilCore.General.toUpperCaseDto(dto);
                editar(dto);
                mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
                recursosManager.showMessage(mensajeTrx);
                to = "";//retroceder();
            } catch (Exception ex) {
                mensajeTrx = ex.getMessage();
                recursosManager.showError(ex.getMessage());
                logger.error(mensajeTrx);
                to = null;
            }
        }



        return to;
    }

    /**
     * Metodo para obtener factor de conversion segun moneda
     * @param monedaEntrada
     * @param monedaSalida
     * @param indicador Indica si se necesita el tipo de cambio (1) del dia o  (0) el ultimo
     * @param tipo (1) compra (-1) venta
     * @return 
     */
    public TipoCambioDto obtenerFactorConversionProceso(MonedaDto monedaEntrada, MonedaDto monedaSalida, Boolean indicador, int tipo) {
        TipoCambioDto factor = new TipoCambioDto();
        try {
            List<TipoCambioDto> listatipoCambioA = new ArrayList<TipoCambioDto>();
            listatipoCambioA = this.obtenerFactorConversion(monedaEntrada, monedaSalida, indicador, tipo);

            if (verificarFactor(listatipoCambioA)) {
                factor = listatipoCambioA.get(0);
            } else {
                List<TipoCambioDto> listatipoCambioB = new ArrayList<TipoCambioDto>();
                listatipoCambioB = this.obtenerFactorConversion(monedaSalida, monedaEntrada, indicador, tipo);
                if (verificarFactor(listatipoCambioB)) {
                    factor = listatipoCambioB.get(0);
                    factor.setFactor(this.calcularFactorInverso(factor.getFactor()));
                }
            }

        } catch (Exception ex) {
            recursosManager.showError(ex.getMessage());
        }
        return factor;
    }

    /**
     * Meotodo para realizar proceso de obtener el factor de conversion
     *
     * @param monedaEntrada
     * @param monedaSalida
     * @return
     * @throws DAOException
     */
    public List<TipoCambioDto> obtenerFactorConversion(MonedaDto monedaEntrada, MonedaDto monedaSalida, Boolean indicador, int tipo) throws DAOException {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        List<Object> listaParametros = new ArrayList<Object>();
        String fechaActual = UtilCore.Fecha.formatearFecha(UtilCore.Fecha.obtenerFechaActualDate(), "dd-MM-yyyy");
        String hqsql = "select e from TipoCambioDto as e where ";
        hqsql += " e.monedaDto.id = " + monedaEntrada.getId();
        hqsql += " and e.monedaCambioDto.id = " + monedaSalida.getId();
        if(tipo == 1){
            hqsql += " and e.tipo = 'COMPRA'";    
        }else if (tipo == -1){
            hqsql += " and e.tipo = 'VENTA'";
        }
        if (indicador) {
            hqsql += " and (to_char(e.fechaCambio, 'DD-MM-YYYY') = '" + fechaActual + "')";
        }
        hqsql += " and e.estado = ?";
        listaParametros.add(Boolean.TRUE);
        if (sessionMBean.getOrganizacionDto() != null && sessionMBean.getOrganizacionDto().getId() != null) {
            hqsql += " and e.organizacionDto.id = ?";
            listaParametros.add(sessionMBean.getOrganizacionDto().getId());
        }
        hqsql += " order by e.fechaCambio desc";
        return springHibernateDao.ejecutarQuery(hqsql, listaParametros);
    }

    /**
     * metodo para verifica el factor de conversion
     *
     * @param lista
     * @return
     */
    public Boolean verificarFactor(List<TipoCambioDto> lista) {
        if (lista.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Metodo para Calcular el nuevo factor de conversion inverso
     *
     * @param factor
     * @return
     */
    public BigDecimal calcularFactorInverso(BigDecimal factor) {
        ApplicationMBean applicationMBean = (ApplicationMBean) WebServletContextListener.getApplicationContext().getBean("applicationMBean");
        BigDecimal valor = UtilCore.Numero.dividir(BigDecimal.ONE, factor, applicationMBean.getPrecisionDecimales());
        return valor;
    }

    /**
     * Metodo para inicializar el tipo de cambio
     *
     * @return
     */
    public TipoCambioDto inicializar() {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        ApplicationMBean applicationMBean = (ApplicationMBean) WebServletContextListener.getApplicationContext().getBean("applicationMBean");
        TipoCambioDto dto = new TipoCambioDto();
        dto = new TipoCambioDto();
        dto.setEstado(Boolean.TRUE);
        dto.setOrganizacionDto(sessionMBean.getOrganizacionDto());
        dto.setFechaCambio(UtilCore.Fecha.obtenerFechaActualDate());

        return dto;
    }

    public static Logger getLogger() {
        return logger;
    }

    public static void setLogger(Logger logger) {
        TipoCambioManager.logger = logger;
    }

    public Long getIdEntidad() {
        return idEntidad;
    }

    public void setIdEntidad(Long idEntidad) {
        this.idEntidad = idEntidad;
    }

    public DAOGenerico<TipoCambioDto> getSpringHibernateDao() {
        return springHibernateDao;
    }

    public void setSpringHibernateDao(DAOGenerico<TipoCambioDto> springHibernateDao) {
        this.springHibernateDao = springHibernateDao;
    }

    public RecursosManager getRecursosManager() {
        return recursosManager;
    }

    public void setRecursosManager(RecursosManager recursosManager) {
        this.recursosManager = recursosManager;
    }

    public String getUrl() {
        return url;
    }

    public String getUrlLista() {
        return urlLista;
    }

    public Long getIteracionCompraVenta() {
        return iteracionCompraVenta;
    }
}
